package com.zhu.bitcom.service.impl;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhu.bitcom.mapper.UserInfoMapper;
import com.zhu.bitcom.pojo.UserInfo;
import com.zhu.bitcom.pojo.VO.LoginVo;
import com.zhu.bitcom.pojo.VO.RegisterVo;
import com.zhu.bitcom.service.IUserInfoService;
import com.zhu.bitcom.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements IUserInfoService {
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Override
    public Result userRegister(RegisterVo registerVo) {
        log.info("用户注册开始");
        if (ObjectUtil.isEmpty(registerVo) || ObjectUtil.isEmpty(registerVo.getUserName()) || ObjectUtil.isEmpty(registerVo.getPassword())) {
            return Result.error("用户名或密码不能为空");
        }
        log.info("用户注册入参是：{}", JSON.toJSONString(registerVo));
        UserInfo user = this.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserName, registerVo.getUserName()));
        if (ObjectUtil.isNotEmpty(user)) {
            log.info("用户名已存在");
            return Result.error("用户名已存在");
        }

        String password = registerVo.getPassword();
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(registerVo, userInfo);

        //生成加密盐
        String salt = BCrypt.gensalt();

        // 生成哈希密码
        String hashedPassword = BCrypt.hashpw(password, salt);

        userInfo.setPassword(hashedPassword);
        userInfo.setSalt(salt);
        Result<String> result = userInfoMapper.insert(userInfo) > 0 ? Result.ok("注册成功") : Result.error("注册失败，请重试");
        log.info("用户注册出参是：{}", JSON.toJSONString(result));
        return result;
    }

    @Override
    public Result<SaTokenInfo> userLogin(LoginVo loginVo) {
        log.info("用户登录");
        if (ObjectUtil.isEmpty(loginVo) || ObjectUtil.isEmpty(loginVo.getUserName()) || ObjectUtil.isEmpty(loginVo.getPassword())) {
            log.info("用户名或密码为空");
            return Result.error("用户名或密码不能为空");
        }
        log.info("用户登录入参：{}",JSON.toJSONString(loginVo));
        UserInfo userInfo = getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserName, loginVo.getUserName()));
        if (ObjectUtil.isEmpty(userInfo)) {
            log.info("用户登录：用户名不存在");
            return Result.error("用户名不存在，请检查");
        }
        //验证
        if (!BCrypt.checkpw(loginVo.getPassword(), userInfo.getPassword()))
            return Result.error("密码错误,请检查");

        log.info("satoken执行登录操作");
        StpUtil.login(userInfo.getId());
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        return Result.ok(tokenInfo);

    }

    @Override
    public Result<UserInfo> getUserInfo() {
        return Result.ok(this.getById(StpUtil.getLoginId().toString()));
    }
}
